/*******************************************************************************
  * 文件：KeyCheck.c
  * 作者：zyz
  * 版本：v1.0.0
  * 日期：2017-08-03
  * 说明：按键检测
*******************************************************************************/

/* 头文件 *********************************************************************/
#include "KeyCheck.h"
#include "KeyDispatch.h"
#include "OS_Kernel.h"
#include "DevInfor.h"

/* 宏定义 *********************************************************************/
/* 类型定义 *******************************************************************/
/* 变量定义 *******************************************************************/
KeyCheck_ts sKeyCheck;             // 按键检测
static Timer_ts sKeyCheckTimer;    // 按键检测定时器

/* 函数声明 *******************************************************************/
/* 函数定义 *******************************************************************/

/*******************************************************************************
  * 函数名: void Key_Init(void)
  * 功  能：按键初始化
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void Key_Init(void)
{
    // 初始化按键检测
    sKeyCheck.u32CurrentKeyValue = u32KEY_VALUE_NONE;
    sKeyCheck.u32LastKeyValue    = u32KEY_VALUE_NONE;
    sKeyCheck.u16TimeCount       = 0;
    sKeyCheck.bValidOperation    = TRUE;
    
    // 开启定时检测任务（10ms）
    OS_TimerStart(&sKeyCheckTimer, u16KEY_CHECK_TIME_MSEC, Key_Check);
}

/*******************************************************************************
  * 函数名: void Key_Check(void)
  * 功  能：按键检测
  * 参  数：无
  * 返回值：无
  * 说  明：在10ms定时中调用
*******************************************************************************/
void Key_Check(void)
{
    // 获取当前按键值
    sKeyCheck.u32CurrentKeyValue = Dev_GetKeyValue();

    // 与上次的按键值做判断
    if(sKeyCheck.u32CurrentKeyValue == sKeyCheck.u32LastKeyValue)
    {
        // 如果有按键操作
        if(sKeyCheck.u32CurrentKeyValue != u32KEY_VALUE_NONE)
        {
            // 按键计时
            if(sKeyCheck.u16TimeCount < u16MAX_VALUE)
            {
                sKeyCheck.u16TimeCount++;
            }

            // 短按检测
            if(sKeyCheck.u16TimeCount == u16KEY_PRESS_TIME_MIN)
            {
                // 检查是否为滑条中的按键按下
                if(Key_SliderCheck(sKeyCheck.u32CurrentKeyValue) == FALSE)
                {
                    // 非滑条按键按下，短按处理
                    Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue, eKEY_TYPE_PRESS_DOWN);
                }
            }
            // 长按500ms检测
            else if(sKeyCheck.u16TimeCount == u16KEY_HOLD_500MS_TIME)
            {
                // 长按500ms处理
                Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue,eKEY_TYPE_HOLD_500MS);
            }
            // 长按1000ms检测
            else if(sKeyCheck.u16TimeCount == u16KEY_HOLD_1000MS_TIME)
            {
                // 长按1000ms处理
                Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue,eKEY_TYPE_HOLD_1000MS);
            }
            // 长按1500ms检测
            else if(sKeyCheck.u16TimeCount == u16KEY_HOLD_1500MS_TIME)
            {
                // 长按1500ms处理
                Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue,eKEY_TYPE_HOLD_1500MS);
            }
            // 长按2s检测
            else if(sKeyCheck.u16TimeCount == u16KEY_HOLD_2S_TIME)
            {
                // 长按2s处理
                Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue, eKEY_TYPE_HOLD_2S);
            }
            // 长按3s检测
            else if(sKeyCheck.u16TimeCount == u16KEY_HOLD_3S_TIME)
            {
                // 长按3s处理
                Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue, eKEY_TYPE_HOLD_3S);
            }
            // 长按5s检测
            else if(sKeyCheck.u16TimeCount == u16KEY_HOLD_5S_TIME)
            {
                // 长按5s处理
                Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue, eKEY_TYPE_HOLD_5S);
            }
            // 长按10s检测
            else if(sKeyCheck.u16TimeCount == u16KEY_HOLD_10S_TIME)
            {
                // 长按10s处理
                Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue, eKEY_TYPE_HOLD_10S);
            }
            
            // 连按检测，检查是否到达连按时间
            if((sKeyCheck.u16TimeCount >= u16KEY_CONTINUE_TIME))
            {
                // 到达连按最小时间，根据之后的连按时间划分步长
                if((sKeyCheck.u16TimeCount - u16KEY_CONTINUE_TIME) <= 200 
                    && ((sKeyCheck.u16TimeCount - u16KEY_CONTINUE_TIME) % u16KEY_CONTINUE_STEP_200MS) == 0)
                {
                    // 连按<=2S，步长按照200毫秒
                    Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue, eKEY_TYPE_CONTINUE);
                }
                else if((sKeyCheck.u16TimeCount - u16KEY_CONTINUE_TIME) <= 400 
                        && ((sKeyCheck.u16TimeCount - u16KEY_CONTINUE_TIME) % u16KEY_CONTINUE_STEP_100MS) == 0)
                {
                    // 2S<连按<=4s，步长按照100毫秒
                    Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue, eKEY_TYPE_CONTINUE);
                }
                else if((sKeyCheck.u16TimeCount - u16KEY_CONTINUE_TIME) > 400 
                        && ((sKeyCheck.u16TimeCount - u16KEY_CONTINUE_TIME) % u16KEY_CONTINUE_STEP_50MS) == 0)
                {
                    // 4S<连按，步长按照50毫秒
                    Key_DispatchHandler(sKeyCheck.u32CurrentKeyValue, eKEY_TYPE_CONTINUE);
                }
            }
        }
    }
    else
    {
        // 抬起检测
        if(sKeyCheck.u32CurrentKeyValue == u32KEY_VALUE_NONE)
        {
            if((sKeyCheck.u16TimeCount >= u16KEY_PRESS_TIME_MIN) &&
               (sKeyCheck.u16TimeCount <  u16KEY_PRESS_TIME_MAX))
            {
                // 如果抬起有效
                if(sKeyCheck.bValidOperation == TRUE)
                {
                    Key_DispatchHandler(sKeyCheck.u32LastKeyValue, eKEY_TYPE_PRESS_UP);
                }
            }
            // 清除无效标志
            sKeyCheck.bValidOperation = TRUE;
        }
        // 多按键操作的抬起检测
        else if(sKeyCheck.u32CurrentKeyValue < sKeyCheck.u32LastKeyValue)
        {
            // 多按键操作后的抬起是无效的
            sKeyCheck.bValidOperation = FALSE;
        }

        // 清零时间计时，更新上次按键值
        sKeyCheck.u16TimeCount    = 0;
        sKeyCheck.u32LastKeyValue = sKeyCheck.u32CurrentKeyValue;
    }
}

/***************************** 文件结束 ***************************************/
